<? 

/**
 * Clientes class
 *
 * Esta clase maneja los clientes
 * @author Alejandro Garcia del Rio <alejandro.garciadelrio@elserver.com>
 * @version 1.0
 * @package Clientes
*/
class Clientes extends Core {

	static protected $instancia;
	static protected $opciones = array(
		'filtros' => array(),
		'rpp' => 50, // Resultados por pagina
		'page' => 1, // Numero de pagina por defecto
		'order' => array('c.ctime', 'ASC') // Ordenamiento de listar() con el tipo de ordenamiento (opcional)
	);
	private $count = 0;

	function __construct ($opciones=null) {
		// Llamo al constructor del parent tambien
		parent::__construct();
		// Guardo las opciones si me definio alguna
		if ($opciones)
			$this->opciones($opciones);
	}

	/**
	 * Devuelve una unica instancia de esta clase
	 * 
	 * @return object Instancia de esta clase
	 */
	public static function getInstance() {
		if (!self::$instancia instanceof self)
			self::$instancia = new self;
		return self::$instancia;
	}

	/**
	 * Setea las opciones 
	 * 
	 * @param array $opciones (opcional) Opciones validas para esta clase. Si esta vacio, funciona como un getter.
	 * @return array $opciones Listado de opciones
	 */
	public function opciones ($opciones=null) {
		return self::$opciones = parent::opciones(self::$opciones, $opciones);
	}

	/**
	 * Agrega un nuevo cliente
	 * 
	 * @param array $cliente Los datos del nuevo cliente
	 * @return integer El id del cliente creado
	 */
	public function agregar ($cliente=null) {

		if (!is_array($cliente['cliente']))
			$cliente['cliente'] = $cliente;

		// Valido no duplicar
		//if (Cliente::existe($cliente['cliente']['nombre'], $cliente['cliente']['apellido']))
		//	return ($this)? $this->fail('El cliente ya existe') : false;
			
		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();
		
		// Inserto el registro
		$id_cliente = $db->insert('clientes', $cliente['cliente']);
		
		return $id_cliente;
	}

	/**
	 * Lista los clientes
	 * 
	 * @param string $opciones (Opcional) Opciones validas para esta clase
	 * @return array
	 */
	function listar ($opciones=null) {
		
		// Seteo las opciones
		$opciones = ($this instanceof self)? $this->opciones($opciones) : self::opciones($opciones);

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Obtengo el objeto de sesion
		$Session = ($this)? $this->Session : Session::getInstance();

		// Armo el order by 
		$order = $opciones['order']; $order_by = '';
		if (strstr($order, ','))	$order = explode(',', $order);
		if ( !is_array($order) || (count($order) == 1) || ((count($order) == 2) && (preg_match('/desc|asc/i', $order[1]))) )
			$order = array($order);

		if ($order)
			foreach ($order as $o) 
				$order_by .= ", ".(is_array($o)? $o[0].' '.$o[1] : $o);

		if (!$opciones['rpp'])
			$opciones['rpp'] = 30;

		// Armo los filtros
		$and = '';

		$joins = '';
		// Proceso los filtros de citas
		if ($opciones['filtros']['citas']) {
			if ($opciones['filtros']['citas'] == 'sin')
				$opciones['filtros']['citas'] = " ci.id_cliente IS NULL ";
			elseif ($opciones['filtros']['citas'] == 'futuras')
				$opciones['filtros']['citas'] = " ci.pendiente = 1 ";
			elseif ($opciones['filtros']['citas'] == 'entrevistadas')
				$opciones['filtros']['citas'] = " ci.pendiente = 0 ";
			elseif ($opciones['filtros']['citas'] == 'canceladas')
				$opciones['filtros']['citas'] = " ci.pendiente = 2 ";

			$select = ", IFNULL(DATE(ci.fecha_inicio), '-') cita ";
			$joins .= "LEFT JOIN citas ci ON c.id_cliente = ci.id_cliente";
			$opciones['filtros']['estado'] = "c.id_estado IN (1,2)";
		}

		if ($opciones['filtros'])
			$and .= 'AND '.implode(' AND ', $opciones['filtros']);

		// Busco los dominios
		$query = "SELECT SQL_CALC_FOUND_ROWS c.*, ce.estado, IFNULL(u.nombre, '-') vendedor	$select
				FROM clientes_estados ce, clientes c
				LEFT JOIN usuarios u ON c.id_usuario = u.id_usuario
				$joins
				WHERE c.id_estado = ce.id_estado $and
				GROUP BY c.id_cliente 
				" . ($order? 'ORDER BY '.substr($order_by, 1) : '') . 
				" LIMIT " . (($opciones['page'] - 1) * $opciones['rpp']) . ", " . $opciones['rpp'];
		
		$clientes = array();
		$_clientes = $db->get_results($query);

		foreach ($_clientes as $_cliente)
				$clientes[$_cliente['id_cliente']] = $_cliente;

		// Calculo la cantidad de resultados
		$count = $db->get_var("SELECT FOUND_ROWS()");
		if ($this instanceof self)
			$this->count = $count;
		
		// Calculo la cantidad de paginas
		$paginas = ($this instanceof self)? $this->paginas() : self::paginas($count, $opciones['rpp']);
		
		return array('data' => $clientes, 'paginas' => $paginas, 'resultados' => $count, 'current' => $opciones['page']);
	}
	
	/**
	 * Devuelve la cantidad de paginas que devolvio la consulta
	 * 
	 * Los resultados son cargados previamente por la funcion listar
	 * @param array $count (Opcional) Cantidad total se resultados
	 * @param array $rpp (Opcional) Cantidad de resultados por pagina
	 * @return integer Cantidad de resultados
	 */
	public function paginas ($count=null, $rpp=null) {

		$rpp = (!$rpp)? self::$opciones['rpp'] : $rpp;
		$count = (!$count && $this instanceof self)? $this->count() : $count;

		// No se puede dividir por 0
		if ($rpp == 0)
			return 0;

		return ceil($count/$rpp);
	}
	
	/**
	 * Devuelve cuantos resultados hay en la consulta
	 * 
	 * Los resultados son cargados previamente por la funcion listar
	 * @return integer Cantidad de resultados
	 */
	public function count () {
		return $this->count;
	}

	/**
	 * Devuelve el listado de estados de los clientes
	 * 
	 * @return array
	 */
	public function estados () {

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Obtengo los estados 
		$estados = array();
		if ($_estados = $db->get_results("SELECT * FROM clientes_estados"))
			foreach ($_estados as $_estado)
				$estados[$_estado['id_estado']] = $_estado['estado'];

		return $estados;
	}

	/**
	 * Devuelve el listado de estados de los clientes y la cantidad de clientes en cada uno
	 * 
	 * @return array
	 */
	public function estados_cantidad () {

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Armo el query
		$query = "SELECT ce.*, COUNT(c.id_cliente) cantidad
		FROM clientes_estados ce
		LEFT JOIN clientes c ON ce.id_estado = c.id_estado
		WHERE 1=1
		GROUP BY ce.id_estado";

		// Obtengo los estados 
		$estados = array();
		if ($_estados = $db->get_results($query))
			foreach ($_estados as $_estado)
				$estados[$_estado['id_estado']] = $_estado;

		return $estados;
	}

	/**
	 * Devuelve el listado de usuarios con la cantidad de clientes asignados a cada uno
	 * 
	 * @return array
	 */
	public function usuarios () {

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Armo el query
		$query = "SELECT u.nombre, u.id_usuario, COUNT(c.id_cliente) cantidad
		FROM usuarios u
		LEFT JOIN clientes c ON u.id_usuario = c.id_usuario
		WHERE 1=1
		GROUP BY u.id_usuario
		ORDER BY u.nombre";

		// Obtengo los estados 
		$usuarios = array();
		if ($_usuarios = $db->get_results($query))
			foreach ($_usuarios as $_usuario)
				$usuarios[$_usuario['id_usuario']] = $_usuario;

		// Agrego los clientes que no tienen ningun empleado asignado
		$usuarios[0] = array('nombre' => 'Sin asignar', 'id_usuario' => 0, 'cantidad' => $db->get_var("SELECT COUNT(*) FROM clientes WHERE id_usuario = 0"));

		return $usuarios;
	}

	/**
	 * Devuelve el listado de origenes de los clientes
	 * 
	 * @return array
	 */
	public function origenes () {

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		// Armo el query
		$query = "SELECT * FROM clientes_origenes WHERE 1=1 ORDER BY origen";

		// Obtengo los estados 
		$origenes = array();
		if ($_origenes = $db->get_results($query))
			foreach ($_origenes as $_origen)
				$origenes[$_origen['id_origen']] = $_origen;

		return $origenes;
	}

	/**
	 * Descarga el listado de cliente generado con los parametros recibidos en formato excel
	 * 
	 * @param string $opciones (Opcional) Opciones validas para esta clase
	 * @return array
	 */
	function excel ($opciones=null) {

		// Configuraciones de formato
		$field 	= "\t"; // Separador de campos
		$line	= "\n"; // Separador de lineas
		$escape = ""; // Escape de caracteres
		$enclose = ''; // Enclose de los campos

		// Obtengo el listado
		$listado = $this->listar($opciones);

		// Defino el string de salida
		$out = '';

		// Obtengo los encabezados
		$headers = array_keys(current($listado['data']));
		
		// Agrego los encabezados 
		$out = implode($field, $headers).$line;
		
		// Recorro los resultados 
		foreach ($listado['data'] as $items) {
			$items['comentario'] = '';
			$out .= implode($field, array_values($items)).$line;
//			$out .= $enclose.implode($enclose.$field.$enclose, array_values($items)).$enclose.$line;
		}

		// Envio los encabezados de descarga
		header('Content-Type: ' . $mime_type);
		header('Content-Disposition: attachment; filename="Clientes.csv"');
		header("Content-Transfer-Encoding: binary");
		header('Accept-Ranges: bytes');
		header("Cache-control: private");
		header('Pragma: private');
		header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

        echo $out;
        flush();
		exit;
	}

	/**
	 * Devuelve el listado de estados relacionados a las citas para armar el filtro
	 * 
	 * @return array
	 */
	public function citas () {

		// Obtengo el objeto de base de datos
		$db = ($this)? $this->db : ez_sql::getInstance();

		$titulos = array (
			-1 	=> array('nombre' => 'Sin entrevistar', 'filtro' => 'sin'),
			0 	=> array('nombre' => 'Entrevistadas', 'filtro' => 'entrevistadas'),
			1 	=> array('nombre' => 'Entrevistas futuras', 'filtro' => 'futuras'),
			2 	=> array('nombre' => 'Entrevista cancelada', 'filtro' => 'canceladas'),
		);

		// Armo el query
		$__citas = $db->get_results("SELECT ci.pendiente estado, COUNT(DISTINCT(ci.id_cliente)) cantidad 
				FROM clientes cl, citas ci
				WHERE cl.id_estado IN (1,2) AND cl.id_cliente = ci.id_cliente 
				GROUP BY estado
				ORDER BY estado");

		if ($__cita = $db->get_row("SELECT '-1' estado, COUNT(DISTINCT(cl.id_cliente)) cantidad 
				FROM clientes cl
				LEFT JOIN citas ci ON cl.id_cliente = ci.id_cliente
				WHERE cl.id_estado IN (1,2) AND ci.id_cita IS NULL"))
			$__citas[] = $__cita;

		$_citas = array();
		foreach ($__citas as $__cita)
			$_citas[$__cita['estado']] = $__cita['cantidad'];
			
		// Obtengo las citas
		foreach ($titulos as $k => $titulo)
			$citas[$titulo['filtro']] = array(
							'nombre' => $titulo['nombre'], 
							'cantidad' => (int)$_citas[$k],
			);

		return $citas;
	}

}

?>
